package vn.bus.bk.adapter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class SQLiteAdapter extends SQLiteOpenHelper {

    public static String databaseName = "bustable.sqlite";
    @SuppressLint("SdCardPath")
    private static final String DATABASE_PATH = "/data/data/vn.bus.bk/";
    private static final String DATABASE_TABLE_BUS_HN = "busHN";
    private static final String DATABASE_TABLE_BUS_HCM = "busHCM";
    private static final String DATABASE_TABLE_PLACE_HN = "placeHN";
    private static final String DATABASE_TABLE_PLACE_HCM = "placeHCM";
    private static SharedPreferences getPrefs;
    public static final String PREFS_NAME = "MyPreference";
    public static final String CITY = "city";

    String key = "chungtb21";

    private static int nameCity;
    private SQLiteDatabase myDB;
    private static Context mContext;

    // Create contructor
    public SQLiteAdapter(Context context) {
	super(context, databaseName, null, 1);
	// TODO Auto-generated constructor stub
	mContext = context;
	getNameCity(mContext);
    }
    
    public static int getNameCity(Context context){
	getPrefs = context.getSharedPreferences(PREFS_NAME, 0);
	nameCity = getPrefs.getInt(CITY, 1);
	Log.i("NAME CITY", String.valueOf(nameCity));
	return nameCity;
    }
    
    public static void setNameCity(int nameCity){
	Editor edit = getPrefs.edit();
	edit.putInt(CITY, nameCity);
	edit.commit();
    }

    @Override
    public void onCreate(SQLiteDatabase arg0) {
	// TODO Auto-generated method stub

    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
	// TODO Auto-generated method stub

    }

    // Copy data from sqlitle file
    public void copyDataBase() throws Exception {

	// InputStream myInput = mContext.getAssets().open(databaseName);

	String outFileName = DATABASE_PATH + databaseName;

//	OutputStream myOutput = new FileOutputStream(outFileName);

//	InputStream myInput = mContext.getAssets().open(databaseName);
//	byte[] buffer = new byte[1024];
//	int length;
//
//	while ((length = myInput.read(buffer)) > 0) {
//
//	    myOutput.write(buffer, 0, length);
//
//	}
//	myOutput.flush();
//	myOutput.close();
//	myInput.close();

	InputStream fis2;
	try {
	    fis2 = mContext.getAssets().open(databaseName);
	    OutputStream fos2 = new FileOutputStream(outFileName);
	    decrypt(key, fis2, fos2);
	} catch (Throwable e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}

    }

    // Open data
    public void openDataBase() throws Exception {
	if (myDB == null || (myDB != null && !myDB.isOpen())) {
	    String myPath = DATABASE_PATH + databaseName;
	    myDB = SQLiteDatabase.openDatabase(myPath, null,
		    SQLiteDatabase.OPEN_READWRITE);

	    Log.v("DATABASE", "OPEN");
	}

    }

    // Close data
    public synchronized void close() {
	if (myDB != null && myDB.isOpen())
	    myDB.close();

	File file = new File(DATABASE_PATH + databaseName);
	file.delete();
	super.close();

    }

    // get All field in database table bus
    public Cursor rawAll() throws Exception {
	String[] columns = { "number", "routeGo", "routeBack", "name",
		"timeStart", "timeEnd", "frequency", "value", "ordinateGo",
		"ordinateBack" };
	if (nameCity == 1) {
	    return myDB.query(DATABASE_TABLE_BUS_HN, columns, null, null, null,
		    null, null);
	} else {
	    return myDB.query(DATABASE_TABLE_BUS_HCM, columns, null, null,
		    null, null, null);
	}
    }

    public Cursor rawAllHN() throws Exception {
	String[] columns = { "number", "routeGo", "routeBack", "name",
		"timeStart", "timeEnd", "frequency", "value", "ordinateGo",
		"ordinateBack" };
	return myDB.query(DATABASE_TABLE_BUS_HN, columns, null, null, null,
		null, null);
    }

    public Cursor rawAllHCM() throws Exception {
	String[] columns = { "number", "routeGo", "routeBack", "name",
		"timeStart", "timeEnd", "frequency", "value", "ordinateGo",
		"ordinateBack" };
	return myDB.query(DATABASE_TABLE_BUS_HCM, columns, null, null, null,
		null, null);
    }

    // get All field in database table place
    public Cursor rawAllPlace() throws Exception {
	String[] columns = { "type", "name", "streets" };
	if(nameCity==1){
	    return myDB.query(DATABASE_TABLE_PLACE_HN, columns, null, null, null,
			null, null);
	}else{
	    return myDB.query(DATABASE_TABLE_PLACE_HCM, columns, null, null, null,
			null, null);
	}
    }

    public static void decrypt(String key, InputStream is, OutputStream os)
	    throws Throwable {
	encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
    }

    public static void encryptOrDecrypt(String key, int mode, InputStream is,
	    OutputStream os) throws Throwable {

	DESKeySpec dks = new DESKeySpec(key.getBytes());
	SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
	SecretKey desKey = skf.generateSecret(dks);
	Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for
						   // SunJCE

	if (mode == Cipher.ENCRYPT_MODE) {
	    cipher.init(Cipher.ENCRYPT_MODE, desKey);
	    CipherInputStream cis = new CipherInputStream(is, cipher);
	    doCopy(cis, os);
	} else if (mode == Cipher.DECRYPT_MODE) {
	    cipher.init(Cipher.DECRYPT_MODE, desKey);
	    CipherOutputStream cos = new CipherOutputStream(os, cipher);
	    doCopy(is, cos);
	}
    }

    public static void doCopy(InputStream is, OutputStream os)
	    throws IOException {
	byte[] bytes = new byte[64];
	int numBytes;
	while ((numBytes = is.read(bytes)) != -1) {
	    os.write(bytes, 0, numBytes);
	}
	os.flush();
	os.close();
	is.close();
    }
}
